<?php
if(!defined(SCOT_DB)) {
	define('SCOT_DB', true);
	
	define('OBJECT', 'OBJECT', true);
	define('ARRAY_A', 'ARRAY_A', false);
	define('ARRAY_N', 'ARRAY_N', false);

	if(!defined('SAVEQUERIES')) define('SAVEQUERIES', false);

	class DB {
		//var $num_queries = 0;
		//var $last_query;
		var $col_info;
		//var $queries;
		var $dbconn;

		/**
		 * Connects to the database server and selects a database
		 * @param string $dbuser
		 * @param string $dbpassword
		 * @param string $dbname
		 * @param string $dbhost
		 */
		function DB() {
			$this->dbconn = @mysql_connect(DB_HOST, DB_USER, DB_PASSWORD);
			
			@mysql_select_db(DB_NAME, $this->dbconn);
		}

		function flush() {
			$this->last_result = array();
			$this->col_info = null;
			//$this->last_query = null;
		}

		function query($query) {
			// filter the query, if filters are available
			// NOTE: some queries are made before the plugins have been loaded, and thus cannot be filtered with this method
			if ( function_exists('apply_filters') )
				$query = apply_filters('query', $query);

			// initialise return
			$return_val = 0;
			$this->flush();

			// Log how the function was called
			$this->func_call = "\$db->query(\"$query\")";

			// Keep track of the last query for debug..
			//$this->last_query = $query;

			// Perform the query via std mysql_query function..
			if (SAVEQUERIES)
				$this->timer_start();

			$this->result = @mysql_query($query, $this->dbconn);
			//++$this->num_queries;
		
			//if (SAVEQUERIES)
				//$this->queries[] = array( $query, $this->timer_stop() );

			// If there is an error then take note of it..
			if ( mysql_error($this->dbconn) ) {
				//$this->print_error();
				return false;
			}

			if ( preg_match("/^\\s*(insert|delete|update|replace) /i",$query) ) {
				$this->rows_affected = mysql_affected_rows();
				// Take note of the insert_id
				if ( preg_match("/^\\s*(insert|replace) /i",$query) ) {
					$this->insert_id = mysql_insert_id($this->dbconn);
				}
				// Return number of rows affected
				$return_val = $this->rows_affected;
			} else {
				$i = 0;
				while ($i < @mysql_num_fields($this->result)) {
					$this->col_info[$i] = @mysql_fetch_field($this->result);
					$i++;
				}
				$num_rows = 0;
				while ( $row = @mysql_fetch_object($this->result) ) {
					$this->last_result[$num_rows] = $row;
					$num_rows++;
				}

				@mysql_free_result($this->result);

				// Log number of rows the query returned
				$this->num_rows = $num_rows;

				// Return number of rows selected
				$return_val = $this->num_rows;
			}

			return $return_val;
		}

		/**
		 * Get one variable from the database
		 * @param string $query (can be null as well, for caching, see codex)
		 * @param int $x = 0 row num to return
		 * @param int $y = 0 col num to return
		 * @return mixed results
		 */
		function get_var($query=null, $x = 0, $y = 0) {
			$this->func_call = "\$db->get_var(\"$query\",$x,$y)";
			if ( $query )
				$this->query($query);

			// Extract var out of cached results based x,y vals
			if ( $this->last_result[$y] ) {
				$values = array_values(get_object_vars($this->last_result[$y]));
			}

			// If there is a value return it else return null
			return (isset($values[$x]) && $values[$x]!=='') ? $values[$x] : null;
		}

		/**
		 * Get one row from the database
		 * @param string $query
		 * @param string $output ARRAY_A | ARRAY_N | OBJECT
		 * @param int $y row num to return
		 * @return mixed results
		 */
		function get_row($query = null, $output = OBJECT, $y = 0) {
			$this->func_call = "\$db->get_row(\"$query\",$output,$y)";
			if ( $query )
				$this->query($query);
			
			if ( !isset($this->last_result[$y]) )
				return null;

			if ( $output == OBJECT ) {
				return $this->last_result[$y] ? $this->last_result[$y] : null;
			} elseif ( $output == ARRAY_A ) {
				return $this->last_result[$y] ? get_object_vars($this->last_result[$y]) : null;
			} elseif ( $output == ARRAY_N ) {
				return $this->last_result[$y] ? array_values(get_object_vars($this->last_result[$y])) : null;
			} else {
				//$this->print_error(" \$db->get_row(string query, output type, int offset) -- Output type must be one of: OBJECT, ARRAY_A, ARRAY_N");
			}
		}

		/**
		 * Gets one column from the database
		 * @param string $query (can be null as well, for caching, see codex)
		 * @param int $x col num to return
		 * @return array results
		 */
		function get_col($query = null , $x = 0) {
			if ( $query )
				$this->query($query);

			// Extract the column values
			for ( $i=0; $i < count($this->last_result); $i++ ) {
				$new_array[$i] = $this->get_var(null, $x, $i);
			}
			return $new_array;
		}

		/**
		 * Return an entire result set from the database
		 * @param string $query (can also be null to pull from the cache)
		 * @param string $output ARRAY_A | ARRAY_N | OBJECT
		 * @return mixed results
		 */
		function get_results($query = null, $output = OBJECT) {
			$this->func_call = "\$db->get_results(\"$query\", $output)";

			if ( $query )
				$this->query($query);

			// Send back array of objects. Each row is an object
			if ( $output == OBJECT ) {
				return $this->last_result;
			} elseif ( $output == ARRAY_A || $output == ARRAY_N ) {
				if ( $this->last_result ) {
					$i = 0;
					foreach( $this->last_result as $row ) {
						$new_array[$i] = (array) $row;
						if ( $output == ARRAY_N ) {
							$new_array[$i] = array_values($new_array[$i]);
						}
						$i++;
					}
					return $new_array;
				} else {
					return null;
				}
			}
		}

		/**
		 * Grabs column metadata from the last query
		 * @param string $info_type one of name, table, def, max_length, not_null, primary_key, multiple_key, unique_key, numeric, blob, type, unsigned, zerofill
		 * @param int $col_offset 0: col name. 1: which table the col's in. 2: col's max length. 3: if the col is numeric. 4: col's type
		 * @return mixed results
		 */
		function get_col_info($info_type = 'name', $col_offset = -1) {
			if ( $this->col_info ) {
				if ( $col_offset == -1 ) {
					$i = 0;
					foreach($this->col_info as $col ) {
						$new_array[$i] = $col->{$info_type};
						$i++;
					}
					return $new_array;
				} else {
					return $this->col_info[$col_offset]->{$info_type};
				}
			}
		}

		/**
		 * Starts the timer, for debugging purposes
		 */
		function timer_start() {
			$mtime = microtime();
			$mtime = explode(' ', $mtime);
			$this->time_start = $mtime[1] + $mtime[0];
			return true;
		}

		/**
		 * Stops the debugging timer
		 * @return int total time spent on the query, in milliseconds
		 */
		function timer_stop() {
			$mtime = microtime();
			$mtime = explode(' ', $mtime);
			$time_end = $mtime[1] + $mtime[0];
			$time_total = $time_end - $this->time_start;
			return $time_total;
		}
	}
	
	$db = null;
	
	function GetDB() {
		if(!isset($db)) {
			$db = new DB();
		}
		return $db;
	}
}
?>